import { defineStore } from 'pinia'
import { ref } from 'vue'
import { reqLogin, reqUserInfo } from '@/api/user'
import pinia from '@/store'
import router from '@/router'
import cloneDeep from 'lodash/cloneDeep'

import { constantRoutes, asyncRoutes, anyRoute } from '@/router/routes'

/**
 *
 * @param {*} userRoutes 用户的权限路由name表示组成的数组 ['goodslist','goodsadd']
 * @param {*} fullAsyncRoutes 动态路由表的完整信息
 * @return 获取用户在完整路由中的详细信息
 */
const genAccessRoutes = (userRoutes, allAsyncRoutes) => {
  return allAsyncRoutes.filter((route) => {
    // 判断用户是否含有此路由的name标识
    if (userRoutes.includes(route.name)) {
      // 子路由也要对比
      if (route.children && route.children.length > 0) {
        route.children = genAccessRoutes(userRoutes, route.children)
      }
      return true
    }
  })
}

const useUserStore = defineStore(
  'user',
  () => {
    const token = ref('') // 用户token
    const userInfo = ref({}) // 用户信息
    const menuRoutes = ref([]) // 用户路由权限

    // 登录
    const login = async (data) => {
      let { code, token: accessToken } = await reqLogin(data)
      if (code === 20000) {
        token.value = accessToken
      }
    }

    // 退出
    const logout = () => {
      token.value = ''
      userInfo.value = {}
      menuRoutes.value = []
    }

    // 获取用户信息
    const getUserInfo = async () => {
      let { data } = await reqUserInfo(token.value)
      userInfo.value = data
      // 1.根据用户接口返回的菜单权限name名称，需要获取其在路由表中完整的信息
      const userAccessRoutes = genAccessRoutes(
        userInfo.value.routes,
        // 注意：需要把动态路由进行深拷贝，否则会影响下一个登录用户的权限
        cloneDeep(asyncRoutes)
      )
      console.log('后台返回路由权限name', userInfo.value.routes)
      console.log('完整路由权限信息：', userAccessRoutes)
      // 2.将上面生成的完整的动态路由信息和常量路由进行合并,存入到pinia中
      menuRoutes.value = [...constantRoutes, ...userAccessRoutes, anyRoute]
      // 3.要加合并的路由信息动态的通过 router.addRoute() 添加到路由器中
      ;[...userAccessRoutes, anyRoute].forEach((route) => {
        router.addRoute(route)
      })
    }

    return {
      token,
      userInfo,
      menuRoutes,
      getUserInfo,
      login,
      logout,
    }
  },
  {
    persist: {
      // 仅持久化token
      paths: ['token'],
    },
  }
)

// 为了可以在组件外获取此仓库
export function useUserStoreHook() {
  return useUserStore(pinia)
}

export default useUserStore
